﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Data.OleDb;
using System.Text;

namespace Com.Toook.Common
{
    /// <summary>
    ///PageData 保存各个分类的记录总数、标题、关键字、描述信息
    /// </summary>
    public class PageData
    {
        //PageColumn字段顺序必须和PageData中的sql查询列顺序相同
        private static string sqlPageParam = " select id, typeId, typeCode, typeName, typeTotalCount, title, keyword, description, newsSiteId, parentId from ShowPageParam;";
        private static string sqlNewsSite = " select SiteId, SiteName from RssSites;";        
        
        /// <summary>
        /// 保存showPageParamTable表中的分页、标题、关键字、描述信息
        /// </summary>
        private static DataTable showPageParamTable = new DataTable();

        /// <summary>
        /// 保存新闻站点类型名称
        /// </summary>
        private static DataTable newsSiteTable = new DataTable();
        public PageData()
        {
        }
        
        /// <summary>
        /// 根据id获取对应的地区名称(欧美、大陆)
        /// </summary>
        /// <param name="areaId">地区id</param>
        /// <returns></returns>
        public static string GetArea(object areaId)
        {
            string area = "未知";
            if (areaId != null && areaId.ToString() != "")
            {
                area = GetTypeName(areaId.ToString());
                if (area == null)
                {
                    area = "未知";
                }
            }          
            return area;
        }
        /// <summary>
        /// 根据类型id获取电影类型名称(喜剧、动作)
        /// </summary>
        /// <param name="typeId"></param>
        /// <returns></returns>
        public static string GetMovieTypeName(object typeId)
        {
            string name = "电影";
            if (typeId != null && typeId.ToString() != "")
            {
                name = GetTypeName(typeId.ToString());
                if (name == null)
                {
                    name = "电影";
                }
            }
            return name;
        }
        /// <summary>
        /// 从表TypeParam，根据typeId获取typeName. 没有对应的返回null
        /// </summary>
        /// <param name="typeId"></param>
        /// <returns></returns>
        public static string GetTypeName(string typeId)
        {
            string typeName = null;
            if (string.IsNullOrEmpty(typeId))
            {
                return typeName;
            }
            DataRow row = SelectParamRow("typeId=" + typeId);
            if (row != null)
            {
                typeName = row["typeName"].ToString();
            }
            return typeName;
        }
        /// <summary>
        /// 获取ShowPageParam表中的行数据。没有满足的返回null
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public static DataRow SelectParamRow(string condition)
        {
            if (showPageParamTable.Rows.Count == 0)
            {
                RefreshPageParam();
            }

            DataRow[] rows = showPageParamTable.Select(condition);

            if (rows.Length > 0)
            {
                return rows[0];
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 获取ShowPageParam表中的行数据。
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public static DataRow[] SelectParamRows(string condition)
        {
            if (showPageParamTable.Rows.Count == 0)
            {
                RefreshPageParam();
            }

            DataRow[] rows = showPageParamTable.Select(condition);

            return rows;           
        }
        /// <summary>
        /// 获取满足条件的ShowPageParam表的数据
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        //public static DataTable GetShowPageParamTable(string condition)
        //{
        //    DataTable table = new DataTable();
        //    table = showPageParamTable.Clone();
        //    DataRow[] dr = showPageParamTable.Select(condition);
        //    for (int i = 0; i < dr.Length; i++)
        //    {
        //        table.ImportRow((DataRow)dr[i]);
        //    }
        //    return table;//返回的查询结果
        //}
        /// <summary>
        /// 根据新闻站点ID，获取新闻站点RssSites数据
        /// </summary>
        /// <param name="newsSiteId">新闻站点id.如101</param>
        /// <returns></returns>
        public static DataRow SelectNewsSiteRow(string newsSiteId)
        {
            if(newsSiteTable.Rows.Count == 0)
            {
                RefreshPageParam();
            }

            DataRow[] rows = newsSiteTable.Select("SiteId=" + newsSiteId);

            if(rows.Length > 0)
            {
                return rows[0];
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 根据byCondition查询出行数据，再获取columnName指定列的值
        /// </summary>
        /// <param name="byCondition">条件(如"typeId=2", "typeName='movie2' ")</param>
        /// <param name="columnName">要获取值的列名枚举PageColumn</param>
        /// <returns>没有返回null</returns>
        public static object GetValue(string byCondition, string columnName)
        {
            DataRow row = SelectParamRow(byCondition);
            if(row != null)
            {
                return row[columnName];
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 根据typeId(如10:所有新闻总数, 31:爱情片总数)
        /// </summary>
        /// <param name="typeId"></param>
        /// <returns></returns>
        public static int GetTotalCount(int typeId)
        {
            DataRow row = SelectParamRow("typeId=" + typeId.ToString());
            if (row == null)
            {
                LogHelper.Log.Error("GetTotalCount错误：typeId=" + typeId);
                return 0;
            }
            int typeTotalCount = int.Parse(row["typeTotalCount"].ToString());
            //ShowPageParam表的typeTotalCount，左边两位是typeId,然后是5个0开始，即100000
            int totalCount = typeTotalCount % (typeId * 100000);
            return totalCount;
        }
        /// <summary>
        /// 生成typePageId的起始、结束值，包含start。如如传31, 1, 10则生成; 310000100, 310001100, 使用时即typePageId>=310000100 and typePageId &lt; 310001100
        /// </summary>
        /// <param name="typeId"></param>
        /// <param name="start"></param>
        /// <param name="pageSize"></param>
        /// <param name="startId"></param>
        /// <param name="endId"></param>
        public static void GetPageStartEndId(int typeId, int start, int pageSize, out int startId, out int endId)
        {
            //310000134, 32-00001-00. 如传31, 1, 10则生成; 310000100, 310001100, 使用时即typePageId >= 310000100 and typePageId < 310001100
            //倒序时，start = total - pageSize * page 可能为0/负,将0/负的start设置为1. 如总数5, 5 - 10 * 1 = -5
            startId = (typeId * 100000 + (start >= 1 ? start : 1)) * 100;
            endId = (typeId * 100000 + (start + pageSize >= 1 ? start + pageSize : 1)) * 100;
        }
        /// <summary>
        /// 生成起始结束条件。如传31, 1, 10则返回“ typePageId >= 310000100 and typePageId &lt; 310001100 ”
        /// </summary>
        /// <param name="typeId"></param>
        /// <param name="start"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public static string GetPageStartEndCondition(int typeId, int start, int pageSize)
        {
            int startId, endId;
            GetPageStartEndId(typeId, start, pageSize, out startId, out endId);
            return " typePageId>=" + startId.ToString() + " and typePageId<" + endId.ToString() + " ";
        }
        /// <summary>
        /// 后台添加数据时，获取分类的下一个显示Id(ShowPageParam中的(typeTotalCount+1)再加两位随机数)。两位类型+5位顺序+两位随机数。如：53 00350 99
        /// </summary>
        /// <param name="typeId"></param>
        /// <returns></returns>
        public static int GetNextTypePageId(int typeId)
        {
            DataRow row = SelectParamRow("typeId=" + typeId.ToString());
            if (row == null)
            {
                throw new Exception("GetNextId 类型错误, typeId=" + typeId.ToString());
            }
            //ShowPageParam表的typeTotalCount，初始是从0开始，如:3100000, 添加一条记录更新为3100001**,后面两位是随机数，防止采集程序顺序读取页面
            int typeTotalCount = int.Parse(row["typeTotalCount"].ToString());
            Random rand = new Random(DateTime.Now.Millisecond + 793);
            int r = rand.Next(100);
            return (typeTotalCount + 1) * 100 + r;
        }
        
        /// <summary>
        /// 新闻自动更新时批量插入数据(ShowPageParam中的typeTotalCount+1)，只返回类型+序号，没有后两位随机数. 如: 52 10234
        /// </summary>
        /// <param name="typeId"></param>
        /// <returns></returns>
        public static int GetNextNewsId(int typeId)
        {
            DataRow row = SelectParamRow("typeId=" + typeId.ToString());
            if (row == null)
            {
                throw new Exception("GetNextId 类型错误, typeId=" + typeId.ToString());
            }            
            int typeTotalCount = int.Parse(row["typeTotalCount"].ToString());
            return typeTotalCount + 1;
        }
        /// <summary>
        /// 获取随机数[0, max)
        /// </summary>
        /// <param name="max"></param>
        /// <param name="feed">种子值</param>
        /// <returns></returns>
        public static int GetRandom(int max, int feed)
        {
            Random rand = new Random(feed + 91357);
            return rand.Next(max);
        }
        /// <summary>
        /// 计算分页开始值。如传入：1, 33, 10返回1. 传入2, 33, 10返回11
        /// </summary>
        /// <param name="page">从url获取的page参数</param>
        /// <param name="total">记录总数</param>
        /// <param name="pageSize">每页显示数</param>
        /// <returns></returns>
        public static int CalculateStart(string page, int total, int pageSize)
        {
            int pageCount = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;//总页数
            int p;
            //页数不为空且是数字，设置页码。否则第一页。
            if(!string.IsNullOrEmpty(page))
            {
                int.TryParse(page, out p);
            }
            else
            {
                p = 1;
            }
            //分页参数不合法
            if(p < 1 || p > pageCount)
            {
                p = 1;
            }

            int start = (p - 1) * pageSize + 1;

            return start;
        }
        /// <summary>
        /// 根据总数、每页显示数，返回合法范围的页数，超出范围的返回1
        /// </summary>
        /// <param name="pageNumber"></param>
        /// <param name="total"></param>
        /// <param name="pageSize"></param>
        /// <returns>超出范围的返回1</returns>
        public static int GetValidPageNumber(int pageNumber, int total, int pageSize)
        {
            int pageCount = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;//总页数
            if (pageNumber < 1 || pageNumber > pageCount)
            {
                pageNumber = 1;
            }
            return pageNumber;
        }
        /// <summary>
        /// 生成分页代码
        /// </summary>
        /// <param name="total">总数</param>
        /// <param name="pageSize">每页显示条数</param>
        /// <param name="currentPage">当前页</param>
        /// <param name="pageHref">要替换页的url,用页数替换pageN: list.aspx?其他参数page=pageN其他参数</param>
        /// <returns></returns>
        public static string GetPageHtml(int total, int pageSize, int currentPage, string pageHref)
        {
            string remark = "pageN";
            StringBuilder sb = new StringBuilder();
            if (total > pageSize)
            {
                int pageCount = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;//总页数                               

                //显示当前页 前、后多少页
                int showPre = 2, showNext = 7;//前2 后7 共10页
                int start, end;
                if (currentPage - showPre <= 1)
                {
                    start = 1;
                }
                else
                {
                    start = currentPage - showPre;
                    sb.Append("<a href=\"" + pageHref.Replace(remark, "1") + "\">首页</a>");
                }

                end = pageCount - currentPage <= showNext ? pageCount : currentPage + showNext;
                if (currentPage > 1)
                {
                    sb.Append("<a href=\"" + pageHref.Replace(remark, (currentPage - 1).ToString()) + "\">上一页</a>");
                }

                for (int i = start; i <= end; i++)
                {
                    if (i == currentPage)
                    {
                        sb.Append("<a href=\"javascript:void(0);\" class=\"currentPage\"");
                    }
                    else
                    {
                        sb.Append("<a href=\"" + pageHref.Replace(remark, i.ToString()) + "\"");
                    }
                    sb.Append(">" + i.ToString());
                    sb.Append("</a>");
                }
                if (currentPage < pageCount)
                {
                    sb.Append("<a href=\"" + pageHref.Replace(remark, (currentPage + 1).ToString()) + "\">下一页</a>");
                }
                if (pageCount - currentPage > showNext)
                {
                    sb.Append("<a href=\"" + pageHref.Replace(remark, pageCount.ToString()) + "\">尾页</a>");
                }
                sb.Append(" 共" + pageCount.ToString() + "页");
            }

            return sb.ToString();
        }
        /// <summary>
        /// 更新typeId分类记录总数和大分类总数
        /// </summary>
        /// <param name="typeId"></param>
        public static void UpdateTypeTotalCount(string typeId)
        {
            DataRow row = SelectParamRow("typeId=" + typeId);
            string parentId = row["parentId"].ToString();
            string updateSub = "update ShowPageParam set typeTotalCount=typeTotalCount+1 where typeId=" + typeId;
            string updateParent = "update ShowPageParam set typeTotalCount=typeTotalCount+1 where typeId=" + parentId;
            OleDbConnection con = AccessHelper.GetConnection();
            OleDbCommand cmd = new OleDbCommand(updateSub, con);
            try
            {
                con.Open();
                cmd.ExecuteNonQuery();

                cmd.CommandText = updateParent;
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                LogHelper.Log.Error("更新ShowPageParam表的typeTotalCount失败，typeId=" + typeId, ex);
            }
            finally
            {
                con.Close();
            }
        }
        /// <summary>
        /// 重新查询数据库，获取分页参数数据表ShowPageParam的新值
        /// </summary>
        public static void RefreshPageParam()
        {
            OleDbConnection con = AccessHelper.GetConnection();
            OleDbDataAdapter daPage = new OleDbDataAdapter(sqlPageParam, con);
            DataSet dsPage = new DataSet();
            try
            {
                daPage.Fill(dsPage);
                showPageParamTable = dsPage.Tables[0];
            }
            catch(Exception ex)
            {
                LogHelper.Log.Fatal("初始化公共页数参数、标题。InitPageData() sqlPageParam", ex);
            }
            ///////////////
            OleDbDataAdapter daNews = new OleDbDataAdapter(sqlNewsSite, con);
            DataSet dsNews = new DataSet();
            try
            {
                daNews.Fill(dsNews);
                newsSiteTable = dsNews.Tables[0];
            }
            catch (Exception ex)
            {
                LogHelper.Log.Fatal("初始化公共新闻站点错误。InitPageData() sqlNewsSite", ex);
            }           
        }
    }

    /// <summary>
    ///PageColumn ShowPageParam表中的字段名
    /// </summary>
    public class PageColumn
    {
        public PageColumn()
        {
        }
        public static string id = "id";
        /// <summary>
        /// 分类的数字ID。如30 
        /// </summary>
        public static string typeId = "typeId";
        /// <summary>
        /// 分类名称加ID。如movie31 
        /// </summary>
        public static string typeCode = "typeCode";
        /// <summary>
        /// 分类名称
        /// </summary>
        public static string typeName = "typeName";
        /// <summary>
        /// 此分类总记录数
        /// </summary>
        public static string typeTotalCount = "typeTotalCount";
        /// <summary>
        /// 此分类页面标题
        /// </summary>
        public static string title = "title";
        /// <summary>
        /// 此分类页面关键字
        /// </summary>
        public static string keyword = "keyword";
        /// <summary>
        /// 此分类页面描述
        /// </summary>
        public static string description = "description";
        /// <summary>
        /// 此新闻分类中站点id列表.逗号隔开，如：101,102,105
        /// </summary>
        public static string newsSiteId = "newsSiteId";
        /// <summary>
        /// 分类的父id. 大类父id=0 (新闻、电影、笑话、文章)，子类父id为(10/30/50/60)
        /// </summary>
        public static string parentId = "";
    }
}